import { isNullOrWhitespace } from '@/utils'
import { Method } from 'alova'
import type { FormInst, DialogOptions } from 'naive-ui'

const ACTIONS = {
  view: '查看',
  edit: '编辑',
  add: '新增'
}

export enum ActionType {
  VIEW = 'view',
  EDIT = 'edit',
  ADD = 'add'
}

export interface CrudOptions {
  title?: string
  name?: string
  initForm?: TRecord<any>
  doCreate?: (_: TRecord<any>) => Method | Promise<any>
  doDelete?: (_: string) => Method | Promise<any>
  doUpdate?: (_: TRecord<any>) => Method | Promise<any>
  refresh?: (_: TRecord<any>) => Method | Promise<any> | void
}

export default function (options: CrudOptions) {
  const { title, name = '', initForm = {}, doCreate, doDelete, doUpdate, refresh } = options

  const modalVisible = ref(false)
  const modalAction = ref('')
  const modalTitle = computed(() => title || ACTIONS[modalAction.value as ActionType] + name)
  const modalLoading = ref(false)
  const modalFormRef: Ref<FormInst | null> = ref(null)
  const modalForm = ref({ ...initForm })

  /** 新增 */
  function handleAdd() {
    modalAction.value = ActionType.ADD
    modalVisible.value = true
    modalForm.value = { ...initForm }
  }

  /** 修改 */
  function handleEdit(row: TRecord<any>) {
    modalAction.value = ActionType.EDIT
    modalVisible.value = true
    modalForm.value = { ...row }
  }

  /** 查看 */
  function handleView(row: TRecord<any>) {
    modalAction.value = ActionType.VIEW
    modalVisible.value = true
    modalForm.value = { ...row }
  }

  /** 保存 */
  function handleSave() {
    if (![ActionType.EDIT, ActionType.ADD].includes(modalAction.value as ActionType)) {
      modalVisible.value = false
      return
    }

    modalFormRef.value?.validate(async (err) => {
      if (err) return

      const actions = {
        add: {
          api: () => doCreate && doCreate(modalForm.value),
          cb: () => window.$message.success('新增成功')
        },
        edit: {
          api: () => doUpdate && doUpdate(modalForm.value),
          cb: () => window.$message.success('编辑成功')
        }
      }
      const action = actions[modalAction.value as keyof typeof actions]

      try {
        modalLoading.value = true
        const data = await action.api()
        action.cb()
        modalLoading.value = modalVisible.value = false
        data && refresh && refresh(data)
      } catch (error) {
        modalLoading.value = false
      }
    })
  }

  /** 删除 */
  function handleDelete(id: string, confirmOptions?: DialogOptions) {
    if (isNullOrWhitespace(id)) return
    window.$dialog.confirm({
      title: '温馨提示',
      content: '是否确定删除？',
      async onPositiveClick() {
        try {
          if (doDelete) {
            modalLoading.value = true
            const data = await doDelete(id)
            window.$message.success('删除成功')
            modalLoading.value = false
            refresh && refresh(data)
          }
        } catch (error) {
          modalLoading.value = false
        }
      },
      ...(confirmOptions || {})
    })
  }

  return {
    modalVisible,
    modalAction,
    modalTitle,
    modalLoading,
    handleAdd,
    handleDelete,
    handleEdit,
    handleView,
    handleSave,
    modalForm,
    modalFormRef
  }
}
